package cn.lyd.org.service.impl;

import cn.lyd.base.enm.EmpStateEnum;
import cn.lyd.base.enm.LogininfoStateEnum;
import cn.lyd.base.enm.ShopAuditLogStateEnum;
import cn.lyd.base.enm.ShopStateEnum;
import cn.lyd.base.until.BaiduAuditUtils;
import cn.lyd.base.until.BussinessException;
import cn.lyd.base.until.SendEmailUtil;
import cn.lyd.org.domain.Employee;
import cn.lyd.org.domain.Shop;
import cn.lyd.org.domain.ShopAuditLog;
import cn.lyd.org.dto.EmployeeDto;
import cn.lyd.org.dto.ShopAuditDto;
import cn.lyd.org.dto.ShopDto;
import cn.lyd.org.mapper.EmployeeMapper;
import cn.lyd.org.mapper.ShopAuditLogMapper;
import cn.lyd.org.mapper.ShopMapper;
import cn.lyd.org.service.IShopService;
import cn.lyd.base.service.impl.BaseServiceImpl;
import cn.lyd.org.vo.ShopVo;
import cn.lyd.user.domain.Logininfo;
import cn.lyd.user.mapper.LogininfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import sun.rmi.runtime.Log;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lyd
 * @since 2022-12-26
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;

    // 注入邮件对象
//    @Autowired
//    private JavaMailSender javaMailSender;

    /**
     * 店铺入驻
     * @param dto
     */
    @Override
    public void settlement(ShopDto dto) {
        // 参数校验
        verify(dto);
        // 保存数据
        save(dto);
    }
    // 店铺入驻： 保存数据
    private void save(ShopDto dto) {
        // 添加 数据
        // 添加 shop
        Shop shop = dto.getShop();
        super.add(shop);


        //添加logininfo
        Logininfo logininfo = new Logininfo();
        logininfo.setUsername(dto.getAdmin().getUsername());
        logininfo.setPhone(dto.getAdmin().getPhone());
        logininfo.setEmail(dto.getAdmin().getEmail());
        //todo 默认盐值密码
        logininfo.setSalt("Uu9BOEjXBZtovzwLAqBjFFZvdus8ClvE");
        logininfo.setPassword("f1374aed7e90d0ab0db4e8ecc32bf95b");
        //后台人员
        logininfo.setType(LogininfoStateEnum.ACTIVITY_BEHIND.getCode());
        logininfo.setDisable(1);
        logininfo.setShop(shop);
        logininfoMapper.add(logininfo);


        // 添加 emp
        Employee emp = new Employee();
        EmployeeDto admin = dto.getAdmin();
        BeanUtils.copyProperties(admin,emp);
        emp.setAge(0);
        emp.setState(EmpStateEnum.ACTIVITY.getCode()); // 员工状态 0：禁用 1：启用
        emp.setLogininfo_id(logininfo.getId());
        emp.setShop_id(shop.getId());
        employeeMapper.add(emp);

        // 修改shop的adminId字段
        Shop updateShop = new Shop();
        updateShop.setId(shop.getId());
        updateShop.setAdmin_id(emp.getId());
        super.update(updateShop);

        //修改logininfo中的shop对象
        Logininfo logininfo1 = new Logininfo();
        BeanUtils.copyProperties(logininfo,logininfo1);
        logininfo1.setId(logininfo.getId());
        logininfo1.setShop(updateShop);
        logininfoMapper.update(logininfo1);

    }
    // 店铺入驻： 参数校验
    private void verify(ShopDto dto) {
        // 1.参数校验

        // 2.两次密码是否一致
        if (!dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())){
            throw new BussinessException("两次密码不一致！");
        }
        // 3. 百度AI审核
        if (!BaiduAuditUtils.TextCensor(dto.getName())){
            throw new BussinessException("店铺名称不合规！");
        }
        if (!BaiduAuditUtils.ImgCensor(dto.getLogo())){
            throw new BussinessException("店铺logo不合规！");
        }


        // 4.店铺是否重复
        String shopName = dto.getName();
        // 根据店铺名称 去查询数据库 如果存在数据 那么就是有 就抛异常
        Shop shopDb = shopMapper.findByName(shopName);
        if (null != shopDb){
            throw new BussinessException("该店铺已经存在，请去登录！");
        }
        // 5.管理员是否已经管理了店铺
        // 根据管理员名称去查询数据是否存在
        String empName = dto.getAdmin().getUsername();
        Employee employee = employeeMapper.findByName(empName);
        if (null != employee && null != employee.getShop_id()){
            // 不为空 且 当前人 属于店铺
            shopDb =  shopMapper.findByAdminId(employee.getId());
            if (null != shopDb){
                throw new BussinessException("当前管理员已经在管理店铺，换个人！");
            }
        }
    }


    /**
     * 店铺审核通过
     * @param dto
     */
    @Override
    public void auditPass(ShopAuditDto dto) {
        // 1.参数校验
        // 2.修改状态为已审核/审核通过/待激活，保存shop
        Shop shop = new Shop();
        shop.setId(dto.getShopId());
        shop.setState(ShopStateEnum.AUDIT_PASS.getCode());
        shopMapper.update(shop);
        // 3.保存日志
        ShopAuditLog log = new ShopAuditLog();
        log.setShop_id(dto.getShopId());
        log.setNote(dto.getNote());
        log.setState(ShopAuditLogStateEnum.AUDIT_PASS.getCode());//店铺审核日志状态：1待审核，2审核通过/待激活，3激活成功，4驳回
        log.setAudit_time(new Date());
        // todo 我们还没有学登录 先写死一个审核人
        log.setAudit_id(1L);
        shopAuditLogMapper.add(log);
        // todo 4.发送邮件 告诉客户成功 并激活
        //   抽取一个工具类 如何在工具类中获取spring的对象
        // 1.创建复杂邮件对象
        SendEmailUtil.send("<h1>尊敬的用户，您的店铺入驻成功，请及时点击下方链接，激活店铺：</h1> " +
                "http://localhost:8080/shop/activate/"+dto.getShopId(),"1064751069@qq.com");


        //1.客户点击激活分配宠物店店长角色 --但是没有权限分配角色--交给后台管理人员审核通过时去分配
        Long shopId = dto.getShopId();
        Logininfo logininfo = logininfoMapper.findByShopId(shopId);
        Employee employee = employeeMapper.findByLogininfoId(logininfo.getId());
        //todo 宠物店店长的角色id 先写死
        List<Long> petAdminRole = new ArrayList<>();
        petAdminRole.add(35L);
        Employee employee1 = new Employee();
        employee1.setId(employee.getId());
        BeanUtils.copyProperties(employee,employee1);
        employee1.setRole_idList(petAdminRole);
        employeeMapper.update(employee1);

        //2.修改 logininfo表
        Logininfo newLogininfo = new Logininfo();
        newLogininfo.setId(employee.getLogininfo_id());
        newLogininfo.setUsername(employee.getUsername());
        newLogininfo.setPhone(employee.getPhone());
        newLogininfo.setEmail(employee.getEmail());
        //修改界面没有密码和盐值，不需要在这修改
        logininfoMapper.update(newLogininfo);

        //3.修改 t_employee_role表
        //先删除
        employeeMapper.deletEmployeeRoleTableByEmpId(employee.getId());
        //再添加
        if (employee1.getRole_idList()!=null){
            employee1.getRole_idList().stream().forEach(roleId->{
                employeeMapper.addEmployeeRoleTable(employee1.getId(),roleId);
            });
        }
    }

    /**
     * 店铺激活
     * @param id //这个id的来源：
     *           1.前端页面点击审核，获取当前行店铺的id后
     *           2.赋值给日志对象的shopId
     *           3.审核通过发送激活邮件时传给用户
     *           4.用户点击链接传给后端激活的接口
     */
    @Override
    public void activate(Long id) {
        /**
         * 修改店铺状态=3    //店铺状态：1待审核，2审核通过/待激活，3激活成功，4驳回
         * -shop对象必须要有店铺id
         */
        Shop shop = shopMapper.findById(id);
        //店铺状态：1待审核，2审核通过/待激活，3激活成功，4驳回
        shop.setState(ShopStateEnum.ACTIVITY.getCode()); //3激活成功
        shopMapper.update(shop);

        //logininfo里设置了一个shop对象，要修改
        Logininfo logininfo1 = new Logininfo();
        Logininfo logininfo = logininfoMapper.findByShopId(id);
        Shop shop1 = logininfo.getShop();
        BeanUtils.copyProperties(logininfo,logininfo1);
        logininfo1.setId(logininfo.getId());
        logininfo1.setShop(shop);
        logininfoMapper.update(logininfo1);
        Logininfo logininfoMapperById = logininfoMapper.findById(logininfo.getId());

        /*//客户点击激活分配宠物店店长角色 --但是没有权限分配角色--交给后台管理人员审核通过时去分配*/

    }

    /**
     * 店铺审核驳回
     *          // 1.参数校验
     *          // 2.修改店铺状态
     *          // 3.店铺审核失败：添加审核日志
     *          //4.发送邮件 告诉客户失败
     * @param dto
     */
    @Override
    public void auditReject(ShopAuditDto dto) {
        //1.参数校验
        //2.修改店铺状态
        //店铺状态：1待审核，2审核通过/待激活，3激活成功，4驳回
        Shop shop = new Shop();
        shop.setId(dto.getShopId());
        shop.setState(ShopStateEnum.AUDIT_NO_PASS.getCode());//4驳回
        shopMapper.update(shop);

        //3.店铺审核驳回：添加审核日志
        //店铺状态：1待审核，2审核通过待激活，3激活成功，4驳回
        ShopAuditLog rejectLog = new ShopAuditLog();
        rejectLog.setState(ShopAuditLogStateEnum.AUDIT_NO_PASS.getCode());//4驳回
        rejectLog.setShop_id(dto.getShopId());
        //todo 设置审核人，先写死，目前没学登录
        rejectLog.setAudit_id(1L);
        rejectLog.setAudit_time(new Date());
        rejectLog.setNote(dto.getNote());
        //添加日志
        shopAuditLogMapper.add(rejectLog);

        // todo 4.发送邮件 告诉客户失败
        //   抽取一个工具类 如何在工具类中获取spring的对象
        // 1.创建复杂邮件对象
        SendEmailUtil.send("<h1>尊敬的用户，您的店铺入驻失败，失败原因：'信息不达标'，请修改信息后重新入驻，修改链接：</h1> " +
                "http://localhost:8081/#/registerAgain/?shopId="+dto.getShopId(),"1064751069@qq.com");

    }


    /**
     * 重新入驻
     *      1.添加新店铺对象,设置新店铺的admin_id
     *      2.修改店长的shop_id
     * @param dto
     */
    @Override
    public void registerAgain(ShopDto dto) {

        //添加shop对象>>>重新审核
        Shop addShop = new Shop();
        addShop.setName(dto.getName());//重置店铺的名字
        addShop.setTel(dto.getTel());//重置店铺的座机
        addShop.setRegisterTime(new Date());//重置店铺的注册时间
        addShop.setState(ShopStateEnum.AUDIT.getCode());//1待审核   // 重置店铺的状态
        addShop.setAddress(dto.getAddress());//重置店铺的地址
        addShop.setLogo(dto.getLogo());//重置店铺的logo


        //通过dto的Admin的username找到店长,
        Employee adminByName = employeeMapper.findByName(dto.getAdmin().getUsername());
        // 获取店长id，赋值给addShop的adminId
        Long id = adminByName.getId();
        addShop.setAdmin_id(id);//重置店铺的admin_id
        shopMapper.add(addShop); //添加shop对象>>>重新审核

        //重置店长的shop_id为新增的店铺的id
        adminByName.setShop_id(addShop.getId());
        employeeMapper.update(adminByName);


    }



    @Override
    public Map<String, Object> loadShopEchartsData() {
        List<ShopVo> shopVos = shopMapper.loadShopEchartsData();
        List<Integer> x = shopVos.stream().map(ShopVo::getState).collect(Collectors.toList());
        List<Integer> y = shopVos.stream().map(ShopVo::getCountNum).collect(Collectors.toList());
        HashMap<String, Object> data = new HashMap<>();
        data.put("x",x);
        data.put("y",y);
        return data;
    }



    /**
     * 批量新增
     * @param shops
     */
    /*@Override
    public void batchAdd(List<Shop> shops) {
        shopMapper.batchAdd(shops);
    }
*/

    /**
     * 删除：删除店铺的同时，删除店长数据
     * @param id
     */
    @Override
    public void delete(Long id) {
        //通过店铺id获取到这个店铺对象
        Shop delShop = shopMapper.findById(id);
        //通过这个店铺对象的admin_id获取到店长的id
        Long adminId = delShop.getAdmin_id();
        //如果有店长就移除店长，没有就不管
        if (adminId!=null){
            //写删除店铺的日志
            setDelLogWithAdmin(id, delShop);

            //1.删除logininfo表
            //1.找到该id对应的员工
            //2.获取该员工的logininfo_id
            //3.删除该员工对应的logininfo数据
            Employee byId = employeeMapper.findById(adminId);
            Long logininfo_id = byId.getLogininfo_id();
            if (logininfo_id!=null){
                logininfoMapper.delete(logininfo_id);
            }
            //2.删除t_employee_role表  员工和角色是一对多的关系,通过employee_id删除效率更高
            employeeMapper.deletEmployeeRoleTableByEmpId(adminId);
            //删除店长
            employeeMapper.delete(adminId);
        }
        //执行删除店铺方法
        super.delete(id);
    }
    //删除店铺：写入日志
    private void setDelLogWithAdmin(Long id, Shop delShop) {
                ShopAuditLog delLog = new ShopAuditLog();
                //删除店铺的备注
                delLog.setNote("删除了"+ delShop.getName()+"店铺和该店的店长");
                //删除时店铺的状态
                delLog.setState(delShop.getState());
                //删除的店铺id
                delLog.setShop_id(id);
                //操作人先写死
                delLog.setAudit_id(1L);
                //删除店铺的时间
                delLog.setAudit_time(new Date());
                //添加日志
                shopAuditLogMapper.add(delLog);
            }




}
